-
Notifications
You must be signed in to change notification settings - Fork 29.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
child_process: ignore undef/proto values of env #15089
Conversation
lib/child_process.js
Outdated
@@ -467,7 +467,10 @@ function normalizeSpawnArguments(file, args, options) { | |||
var envPairs = []; | |||
|
|||
for (var key in env) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should optimally be:
const envPairs = Object.keys(env).filter(Boolean).map(key => `${key}=${env[key]}`)
or something similar (ignore empty keys in addition to undefined ones.
I do think it's underspecified though. So I'll wait for someone who understands it better to weigh in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OMG .filter(Boolean)
💘
I used to do .filter((x) => x)
, but have alway looked for a built-in.
P.S. @Gerhut in TF&I (node 8.3.0 and newer) for ... of
loop are almost 10 time faster than for ... in
loops, and it's supports Object.entries()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@refack but the call to Object.keys
is itself about as slow as doing for... in
- in this particular case I don't think performance is important given the time it takes to create a process and all 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benjamingr agreed.
I'm just promoting TF&I good behaviour (no more CranksharfScript)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the code around still in legacy Syntax, should I be allowed to use modern syntax? If so I will modify them in modern syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Gerhut yes, in general new code should be written in new syntax.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, for..in
includes keys in prototype, and keys-in-prototype of env test exists at https://github.com/nodejs/node/blob/master/test/parallel/test-child-process-env.js#L31-L33 . Changing to Object.keys/entries
will fail them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to remove that test case and only use Object.keys
. There is not much reasoning in the original commit about why it was added but I think this is actually a faulty behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using filter(Boolean)
would be a bad decision to use though as it would remove a empty string and any other falsy value as well.
Tagging as semver-major preemptively since this is a user facing behavioral change in an API marked I don't feel strongly about it - I just don't want it to be missed. |
@Gerhut thank you for the contribution. Just to explain the process at this point:
If at any point you would like assistance with the pull request or have any question about the process feel free to ask here. Welcome. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add documentation notes and function level changelog entries for this.
LGTM as semver-major |
I personally am not convinced about this. Why should |
I'm kind of half-way where @BridgeAR is. I would say |
I think it makes sense to ignore |
100 % totally official twitter poll: https://twitter.com/addaleax/status/903796395865452544 |
Looks like the poll says I personally still think we should not remove it but throw an error instead and the poll did not cover that part but it seems like most people agree on removing it, so I will not hold this off. |
BTW: need to think about how to make this consistent with assignment (maybe in a future PR) Lines 827 to 842 in 98d8db3
|
PR Updated. Moreover, Would "ignore keys in prototype of I just feel this change should be in another PR to discuss separately. There could be an use case that using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general LGTM but I would like my comment to be addressed.
lib/child_process.js
Outdated
@@ -466,8 +466,10 @@ function normalizeSpawnArguments(file, args, options) { | |||
var env = options.env || process.env; | |||
var envPairs = []; | |||
|
|||
for (var key in env) { | |||
envPairs.push(key + '=' + env[key]); | |||
for (const [key, value] of Object.entries(env)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure how fast Object.entries
is and I somewhat expect it to be slower than e.g. using Object.keys
or using for ... in
with a Object.hasOwnProperty.call(env, key)
check. The latter will definitely be faster in upcoming v8 versions but probably not right now.
@Gerhut I think it is fine to keep it in this PR but it would be just as fine to move it to another one! If this is kept in the PR the commit message has to be updated though. This has to be done one way or the other anyway though since it currently has information that is not necessary for landing. So I think it is your call. If you want to land another commit - feel free to open a second PR for that. |
I'm -0. |
Dimissed my ok as I am also -0 on the change but I do not want to block it either.
This is semver major and needs some LGs @nodejs/tsc It is still a tiny bit controversial in general though, so please read all the comments as well. |
I'm on the fence on this one. Deviating from how null and undefined are handled in |
I would be in favour of the same change for process.env |
'HELLO': 'WORLD' | ||
'HELLO': 'WORLD', | ||
'UNDEFINED': undefined, | ||
'NULL': null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add 'EMPTY': ''
doc/api/child_process.md
Outdated
@@ -412,7 +412,8 @@ Use `cwd` to specify the working directory from which the process is spawned. | |||
If not given, the default is to inherit the current working directory. | |||
|
|||
Use `env` to specify environment variables that will be visible to the new | |||
process, the default is [`process.env`][]. | |||
process, the default is [`process.env`][], `undefined` values in `env` will be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion keep the old line, and add a new sentence:
process, the default is [`process.env`][].
`undefined` values in `env` will be ignored.
lib/child_process.js
Outdated
for (var key in env) { | ||
envPairs.push(`${key}=${env[key]}`); | ||
for (const key of Object.keys(env)) { | ||
const value = env[key] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make sure running make lint
passes?
At present, undefined values of env option will be transferred as a "undefined" string value, and values in prototype will also be included, which are not usual behaviors. Since non-string env values & prototype values are undocumented, this change may be treated as a bugfix or a breaking change. Tested on Mac, Windows not yet. Fixes: nodejs#15087
Sorry for only ran |
CI before landing: https://ci.nodejs.org/job/node-test-pull-request/12531/ |
Pushed a fix for Windows. |
At present, undefined values of env option will be transferred as a "undefined" string value, and values in prototype will also be included, which are not usual behaviors. This commit prevents those to be transferred to the environment of the child process. PR-URL: nodejs#15089 Fixes: nodejs#15087 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaël Zasso <targos@protonmail.com>
In future please run CITGM before landing semver major commits edit: for context this broke CITGM |
Sorry about that |
I'll just leave a note here to anyone landing this in the future, it can't land without #18210. |
Before this commit, setting a property of process.env to undefined would set the value to the string "undefined". This changes the behavior to instead remove the value, working like the delete operator. Refs: nodejs#15089
PR-URL: #18990 Refs: #15089 Refs: #18158 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
PR-URL: nodejs#18990 Refs: nodejs#15089 Refs: nodejs#18158 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
At present, undefined values of env option will be transferred as an "undefined" string value and values in the prototype will also be included, which are not usual behaviors.
Since non-string env values & prototype values are undocumented, this change may be treated as a bugfix or a breaking change.
Tested on Mac, Windows not yet.
Fixes: #15087
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
child_process